/**
 * @brief 数据中心头文件
 * @note
 * @par 示例
 * @code
 *
 * user A:
    init:
        TDataCenterInit(A_handle);
    fini:
        TDataCenterFini(A_handle);
    send msg:
        TDataCenterMsg *msg = TDataCenterCreateMsg(content_size);
        msg->receiver = B_handle;
        TDataCenterSendMsg(A_handle, msg);
   user B:
    init:
        TDataCenterInit(B_handle);
    fini:
        TDataCenterFini(B_handle);
    recv msg:
        TDataCenterMsg *msg = TDataCenterPopMsg(B_handle);
        if (msg != NULL)
            ;// deal this msg
            TDataCenterDestroyMsg(msg);
 *
 * @endcode
 */
#ifndef _DATA_CENTER_H_
#define _DATA_CENTER_H_

#include "common/base_type.h"
#include "data_center/data_center_msg_define.h"

/**
 * TDataCenterUser 内部数据中心用户枚举值
 */
enum TDataCenterUserTag
{
    kDataCenterUserShell,   ///< shell
    kDataCenterUserCtrl,    ///< ctrl
    kDataCenterUserScreen,  ///< screen
    kDataCenterUserAd,      ///< ad

    kMpuOtaMsgUserMax,
};
typedef enum TDataCenterUserTag TDataCenterUser;

/**
 * TDataCenterMsgType 内部数据中心交互消息类型枚举值
 */
enum TDataCenterMsgTypeTag
{
    kDataCenterMsgTypeCmdOpenAcc   = 0x0101,  ///< shell->ctrl 打开ACC
    kDataCenterMsgTypeCmdCloseAcc  = 0x0102,  ///< shell->ctrl 关闭ACC
    kDataCenterMsgTypeCmdOpenPwr   = 0x0103,  ///< shell->ctrl 打开PWR
    kDataCenterMsgTypeCmdClosePwr  = 0x0104,  ///< shell->ctrl 关闭PWR

    kDataCenterMsgTypeCtrlResult   = 0x1001,  ///< ctrl->shell 控制结果，消息体见 MsgBodyCtrlResult
    kDataCenterMsgTypeUpdateScreen = 0x1202,  ///< ctrl->screen 立即更新屏幕
};
typedef enum TDataCenterMsgTypeTag TDataCenterMsgType;

#pragma pack(push, 1)
/**
 * TDataCenterMsg 数据中心交互消息结构体
 */
struct TDataCenterMsgTag
{
    UInt8  receiver;     ///< 消息接收者，详见 TDataCenterUser
    UInt16 msg_type;     ///< 消息类型，详见 TDataCenterMsgType
    UInt16 content_len;  ///< 附加内容长度
    UInt8  content[0];   ///< 附加内容
};
typedef struct TDataCenterMsgTag TDataCenterMsg;
#pragma pack(pop)

/**
 * @brief 初始化单个用户
 *
 * @param handle 访问句柄，详见 TDataCenterUser
 */
void TDataCenterInit(TDataCenterUser handle);

/**
 * @brief 去初始化单个用户
 *
 * @param handle 访问句柄，详见 TDataCenterUser
 */
void TDataCenterFini(TDataCenterUser handle);

/**
 * @brief 创建交互消息，内含内存申请
 *
 * @param content_size 附加内存长度
 * @return TDataCenterMsg* 返回的消息，为NULL则内存申请失败
 */
TDataCenterMsg* TDataCenterCreateMsg(UInt16 content_size);

/**
 * @brief 销毁交互消息，内含内存释放
 *
 * @param msg_t 待销毁消息结构体
 */
void TDataCenterDestroyMsg(TDataCenterMsg *msg_t);

/**
 * @brief 发送交互消息，外部申请空间
 *
 * @param handle 访问句柄，详见 TDataCenterUser
 * @param msg_t 待发送消息结构体
 * @return Int32 >=0 发送成功，返回列表内下标，<0 发送失败
 */
Int32 TDataCenterSendMsg(TDataCenterUser handle, TDataCenterMsg *msg_t);

/**
 * @brief 获取交互消息，但不取出，不要在释放空间，否则会造成数据丢失
 *
 * @param handle 访问句柄，详见 TDataCenterUser
 * @return TDataCenterMsg* NULL 表示没有消息，否则返回消息结构体
 */
TDataCenterMsg* TDataCenterPeekMsg(TDataCenterUser handle);

/**
 * @brief 获取交互消息，并取出，外部释放空间
 *
 * @param handle 访问句柄，详见 TDataCenterUser
 * @return TDataCenterMsg* NULL 表示没有消息，否则返回消息结构体
 */
TDataCenterMsg* TDataCenterPopMsg(TDataCenterUser handle);


#endif  ///< _DATA_CENTER_H_
